﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;

//使用一个变量存最小值是不可以的，因为出战之后，假如栈顶是最小的，出栈之后就找不到了
//使用一个单独的栈可以
//也可以在node里面添加 public long min
public class MinStack2
{
    public class MinStackNode {


        public long val;
        //public long min;
        public MinStackNode next;
        public MinStackNode(long val = 0,MinStackNode next=null)
        {
            this.val=val;
            this.next=next;
        }
    }

    MinStackNode top;
    MinStackNode mintop;
    long min = int.MaxValue;
    public MinStack2()
    {
        top=new MinStackNode(0);
         mintop = new MinStackNode(int.MaxValue);
    }

    public void Push(long val)
    {
        MinStackNode newNode = new MinStackNode(val,top);
        min = Math.Min(min, val);//这里不是和最min比较，而是上一个min,-10不是和-20比，而是-20已经出栈，和栈顶的maxvalue比
        min = Math.Min(mintop.val, val);
        MinStackNode newMin = new MinStackNode(min, mintop);
        top = newNode;
        mintop=newMin;
    }

    public void Pop()
    {
      
        top=top.next;
        mintop = mintop.next;
        //空栈的时候需要清空min
     
        

    }

    public long Top()
    {
       
        return top.val;
    }

    public long GetMin()
    {
        long curMin =mintop.val;
        return curMin;
    }
}
//想使用一个变量，每次出栈进栈都要计算一下
public class MinStack
{
    Stack<int> stack=new Stack<int>();
    public int min;


    public MinStack()
    {
        min=int.MaxValue;
    }

    public void Push(int val)
    {
        if(stack.Count == 0)
        {
            
            min = val;
            stack.Push(val - min);
        }
        else
        {
            int diff=val-min;//差值是topval和上一个min的差值

            stack.Push(diff);
            if (diff<0)
            {
                min = val;
            }
        }

       
        

    }

    public void Pop()
    {
        int diff = stack.Pop();
        //更新最小值
        if(diff < 0)//说明栈顶的元素是目前的最小值
        {
            //top=min+diff
            //重新计算最小值premin  int curdiff=curval-premin; 
            // premin=curval-curdiff; curval=min
            //premin=min-curdiff;
            //min = diff+min;
            min = min-diff;
        }

    }

    public int Top()
    {
        int diff = stack.Pop();
        if (diff < 0)//说明栈顶的元素是目前的最小值
        {

            return  min;
        }
        else
        {
            return diff + min;
        }

       
    }

    public int GetMin()
    {
        return min;
    }
}

public class Progam155
{
    static void Main155(string[] args)
    {
        MinStack obj = new MinStack();
        
        obj.Push(2147483646);
        obj.Push(2147483646);
        obj.Push(2147483647);
        Console.WriteLine(obj.Top());
        obj.Pop();
        Console.WriteLine(obj.GetMin());
        obj.Pop();

        Console.WriteLine(obj.GetMin());
        obj.Pop();
        obj.Push(2147483647);
        Console.WriteLine(obj.Top());
        Console.WriteLine("min"+obj.GetMin());

        obj.Push(-2147483648);
        Console.WriteLine(obj.Top());
        Console.WriteLine(obj.GetMin());
        obj.Pop();
        Console.WriteLine(obj.GetMin());
    }

}
